package com.tuling.plugins;

import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

/**
 * 手写分页插件
 */
@Intercepts({
        // 需要代理的对象和方法
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class})
})
public class MyPageInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        System.out.println("简易版本分页插件");
        // 获取所有参数
        Object[] args = invocation.getArgs();
        // Mapper 映射文件的每一个节点都会封装成 MappedStatement
        MappedStatement statement = (MappedStatement) args[0];
        // SQL 参数
        Object sqlArgs = args[1];
        BoundSql boundSql = statement.getBoundSql(sqlArgs);
        // 获取 RowBounds （封装了逻辑分页的参数）
        RowBounds rowBounds = (RowBounds) args[2];
        ResultHandler resultHandler = (ResultHandler) args[3];
        // 获取 SQL 语句拼接 limit
        int offset = rowBounds.getOffset();
        int limit = rowBounds.getLimit();
        String newSql = boundSql.getSql() + " limit " + offset + "," + limit;
        BoundSql newBoundSql = new BoundSql(statement.getConfiguration(), newSql, boundSql.getParameterMappings(), sqlArgs);
        // 被代理对象
        Executor executor = (Executor) invocation.getTarget();
        CacheKey cacheKey = executor.createCacheKey(statement, sqlArgs, rowBounds, newBoundSql);
        // 调用被代理的方法
        return executor.query(statement,sqlArgs,rowBounds,resultHandler,cacheKey,newBoundSql);
    }
}
